#include "kxtj3_driver.h"
#include "public_head.h"




volatile static int kxtjIntFlag = 0;


void app_io_event_handler(app_io_evt_t *p_evt)
{
    app_io_pin_state_t pin_level = APP_IO_PIN_RESET;
//    if (p_evt->arg != NULL)
//    {
//        GR_LOG("%s\r\n", (char *)p_evt->arg);
//    }

    if (p_evt->pin == APP_KXTJ_INT_PIN)
    {
//        pin_level = app_io_read_pin(APP_IO_TYPE_NORMAL, APP_KXTJ_INT_PIN);
//        if (pin_level == APP_IO_PIN_RESET)
//        {
//            EventMask.SBP_INTERRUPT_G_SENSOR_EVT = true;
//        }
        EventMask.SBP_INTERRUPT_G_SENSOR_EVT = true;
    }
}
void kxtj3_int_gpio_init(void)
{
    uint16_t ret;
    app_io_init_t io_init = APP_IO_DEFAULT_CONFIG;
    io_init.pull = APP_IO_PULLDOWN;
    io_init.mode = APP_IO_MODE_IT_RISING;
    io_init.pin  = APP_KXTJ_INT_PIN;
    io_init.mux  = APP_IO_MUX_2;
    
    ret = app_io_event_register_cb(APP_IO_TYPE_AON, &io_init, app_io_event_handler, "kxtj pin interrupt");
    if (ret != APP_DRV_SUCCESS)
    {
        GR_LOG(" [init] APP_KXTJ_INT_PIN init failed.\r\n");
    }
    else
    {
        GR_LOG(" [init] APP_KXTJ_INT_PIN init success.\r\n");
    }
}


int kxtj3_i2c_write_reg(uint8_t regAddr, uint8_t data)
{
    uint8_t txBuff[5];
    txBuff[0] = regAddr;
    txBuff[1] = data;
    
    return user_i2c_trans_recv(0x0E, (uint8_t *)txBuff, 2, NULL, 0);
}


int kxtj3_i2c_read_reg(uint8_t regAddr, uint8_t *pData, int len)
{
    uint8_t txBuff[5];
    txBuff[0] = regAddr;    
    return user_i2c_trans_recv(0x0E, (uint8_t *)txBuff, 1, pData, len);
}





void kxrj3_check(uint8_t addr, uint8_t wData, uint8_t rData)
{
    if(wData != rData)
    {
        GR_LOG(" [kxrj3] addr : %02X, write 0x%02X, read 0x%02X\r\n", addr, wData, rData);
    }
    else
    {
        GR_LOG(" [kxrj3] addr : %02X, write success \r\n", addr);
    }
}



void kxrj3_set_pc1_mode(uint8_t pc1)
{
    uint8_t data = 0;
    kxtj3_i2c_read_reg(KXTJ3_CTRL_REG1, &data, 1);
    data &= 0x7F;
    data |= ((pc1&0x01)<<7);
    kxtj3_i2c_write_reg(KXTJ3_CTRL_REG1, data);
}


void kxrj3_set_ctrl_reg1(uint8_t pc1, uint8_t res , uint8_t drdye , uint8_t gsel, uint8_t wufe)
{
    uint8_t data = ( ((pc1&0x01)<<7) | ((res&0x01)<<6) | ((drdye&0x01)<<5) | ((gsel&0x07)<<2) | ((wufe&0x01)<<1) );
    kxtj3_i2c_write_reg(KXTJ3_CTRL_REG1, data);
}

void kxrj3_set_ctrl_reg2(uint8_t srst, uint8_t dcst , uint8_t owufa , uint8_t owufb, uint8_t owufc)
{
    uint8_t data = ( ((srst&0x01)<<7) | ((dcst&0x01)<<4) | ((owufa&0x01)<<2) | ((owufb&0x01)<<1) | ((owufc&0x01)<<0) );
    kxtj3_i2c_write_reg(KXTJ3_CTRL_REG2, data);
}

void kxrj3_set_int_ctrl_reg1(uint8_t ien, uint8_t iea , uint8_t iel , uint8_t stpol)
{
    uint8_t data = ( ((ien&0x01)<<5) | ((iea&0x01)<<4) | ((iel&0x01)<<3) | ((iel&0x07)<<1) );
    kxtj3_i2c_write_reg(KXTJ3_INT_CTRL_REG1, data);
}

void kxrj3_set_int_ctrl_reg2(uint8_t ulmode, uint8_t xnwue , uint8_t xpwue, uint8_t ynwue , uint8_t ypwue, uint8_t znwue , uint8_t zpwue)
{
    uint8_t data = ( ((ulmode&0x01)<<7) | ((xnwue&0x01)<<5) | ((xpwue&0x01)<<4) | ((ynwue&0x07)<<3) | ((ypwue&0x07)<<2) | ((znwue&0x07)<<1) | ((zpwue&0x07)<<0) );
    kxtj3_i2c_write_reg(KXTJ3_INT_CTRL_REG2, data);
}

void kxrj3_set_data_ctrl_reg(uint8_t osaa, uint8_t osab , uint8_t osac, uint8_t osad)
{
    uint8_t data = ( ((osaa&0x01)<<3) | ((osab&0x01)<<2) | ((osac&0x01)<<1) | ((osad&0x01)<<0) );
    kxtj3_i2c_write_reg(KXTJ3_DATA_CTRL_REG, data);
}

void kxrj3_set_wakeup_counter(uint8_t wufc)
{
    uint8_t data = wufc;
    kxtj3_i2c_write_reg(KXTJ3_WAKEUP_COUNTER, data);
}

void kxrj3_set_na_counter(uint8_t nafc)
{
    uint8_t data = nafc;
    kxtj3_i2c_write_reg(KXTJ3_NA_COUNTER, data);
}


void kxrj3_set_self_test(void)
{
    uint8_t data = 0xCA;
    kxtj3_i2c_write_reg(KXTJ3_SELF_TEST, data);
}

void kxrj3_set_self_test_exit(void)
{
    uint8_t data = 0;
    kxtj3_i2c_write_reg(KXTJ3_SELF_TEST, data);
}

void kxrj3_set_wakeup_threshold(uint16_t threshold)
{
    uint8_t data = (uint8_t)(threshold>>8);
    kxtj3_i2c_write_reg(KXTJ3_WAKEUP_THRESHOLD_H, data);
    data = (uint8_t)threshold;
    kxtj3_i2c_write_reg(KXTJ3_WAKEUP_THRESHOLD_L, data);
}

void kxrj3_get_data(uint8_t *pData)
{
    kxtj3_i2c_read_reg(KXTJ3_XOUT_L, pData, 6);
}



void kxrj3_config_reg(uint8_t addr, uint8_t data)
{
    uint8_t regValue = 0;
    uint8_t writeValue = 0;
    uint8_t readValue = 0;
    uint8_t sourValue = 0;
    uint8_t regAddr = 0;
    
    regAddr = addr;
    writeValue = data;
    kxtj3_i2c_read_reg(regAddr, (uint8_t *)&sourValue, 1);
    kxtj3_i2c_write_reg(regAddr, writeValue);
    kxtj3_i2c_read_reg(regAddr, (uint8_t *)&readValue, 1);
    
    if(writeValue != readValue)
    {
        GR_LOG(" [fail] addr : %02X, sour 0x%02X, write 0x%02X, read 0x%02X\r\n", addr, sourValue, writeValue, readValue);
    }
    else
    {
        GR_LOG(" [pass] addr : %02X, sour 0x%02X, write 0x%02X, read 0x%02X\r\n", addr, sourValue, writeValue, readValue);
    }
}

void kxrj3_reg_con_prin(uint8_t regAddr, uint8_t data)
{
    switch(regAddr)
    {
        case KXTJ3_DCST_RESP:{
            GR_LOG("0x%02X(DCSTR)\r\n", data );
        }break;
        case KXTJ3_WHO_AM_I:{
            GR_LOG("0x%02X(WIA)\r\n", data );
        }break;
        case KXTJ3_INT_SOURCE1:{
            GR_LOG("%d(DRDY), %d(WUFS)\r\n", \
             ((data>>4)&0x01), ((data>>1)&0x01) );
        }break;
        case KXTJ3_INT_SOURCE2:{
            GR_LOG("%d(XNWU), %d(XPWU), %d(YNWU), %d(YPWU), %d(ZNWU), %d(ZPWU)\r\n", \
             ((data>>5)&0x01), ((data>>4)&0x01), ((data>>3)&0x01), ((data>>2)&0x03), ((data>>1)&0x01), ((data>>0)&0x01) );
        }break;
        case KXTJ3_STATUS_REG:{
            GR_LOG("%d(INT)\r\n", ((data>>4)&0x01) );
        }break;
        ////////////////////////////////////////////////////////////////
        case KXTJ3_CTRL_REG1:{
            GR_LOG("%d(PC1), %d(RES), %d(DRDYE), %d(GSEL), %d(EN16G), %d(WUFE)\r\n", \
             ((data>>7)&0x01), ((data>>6)&0x01), ((data>>5)&0x01), ((data>>3)&0x03), ((data>>2)&0x01), ((data>>1)&0x01) );
        }break;
        case KXTJ3_CTRL_REG2:{
            GR_LOG("%d(SRST), %d(DCST), %d(OWUF)\r\n", \
             ((data>>7)&0x01), ((data>>4)&0x01), ((data>>0)&0x07) );
        }break;
        case KXTJ3_INT_CTRL_REG1:{
            GR_LOG("%d(IEN), %d(IEA), %d(IEL), %d(STPOL)\r\n", \
             ((data>>5)&0x01), ((data>>4)&0x01), ((data>>3)&0x01), ((data>>1)&0x03) );
        }break;
        case KXTJ3_INT_CTRL_REG2:{
            GR_LOG("%d(ULMODE), %d(XWUE(N,P)), %d(YWUE(N,P)), %d(ZWUE(N,P))\r\n", \
             ((data>>7)&0x01), ((data>>4)&0x03), ((data>>2)&0x03), ((data>>0)&0x03) );
        }break;
        case KXTJ3_DATA_CTRL_REG:{
            GR_LOG("%d(OSA(A-D))\r\n", \
             ((data>>0)&0x0F) );
        }break;
        case KXTJ3_WAKEUP_COUNTER:{
            GR_LOG("%d(WUFC)\r\n", data );
        }break;
        case KXTJ3_NA_COUNTER:{
            GR_LOG("%d(NAFC)\r\n", data );
        }break;
        case KXTJ3_WAKEUP_THRESHOLD_H:{
            GR_LOG("0x%02X(THRESHOLD_H)\r\n", (data&0x0F) );
        }break;
        case KXTJ3_WAKEUP_THRESHOLD_L:{
            GR_LOG("0x%02X(THRESHOLD_L)\r\n", data );
        }break;
        default:{
            GR_LOG("(NULL)\r\n");
        }break;
    }
}

void kxrj3_reg_value(uint8_t regAddr)
{
    uint8_t regValue = 0;
    if(0 != kxtj3_i2c_read_reg(regAddr, (uint8_t *)&regValue, 1))
    {
        GR_LOG(" [query] <0x%02X> fail \r\n", regAddr);
    }
    else
    {

        GR_LOG(" [query] <0x%02X> 0x%02X -- %d%d%d%d%d%d%d%d -- ", regAddr, regValue, \
                                        (0x01&(regValue>>7)), \
                                        (0x01&(regValue>>6)), \
                                        (0x01&(regValue>>5)), \
                                        (0x01&(regValue>>4)), \
                                        (0x01&(regValue>>3)), \
                                        (0x01&(regValue>>2)), \
                                        (0x01&(regValue>>1)), \
                                        (0x01&(regValue>>0)));
        kxrj3_reg_con_prin(regAddr, regValue);
        

//        GR_LOG(" [query] <0x%02X> 0x%02X -- %d%d%d%d%d%d%d%d\r\n", regAddr, regValue, \
//                                            (0x01&(regValue>>7)), \
//                                            (0x01&(regValue>>6)), \
//                                            (0x01&(regValue>>5)), \
//                                            (0x01&(regValue>>4)), \
//                                            (0x01&(regValue>>3)), \
//                                            (0x01&(regValue>>2)), \
//                                            (0x01&(regValue>>1)), \
//                                            (0x01&(regValue>>0)));
    }
}

void kxrj3_query_reg_value(void)
{
    GR_LOG("-------------------------------------------\r\n");
    GR_LOG("    *** R ***\r\n");
    kxrj3_reg_value(KXTJ3_DCST_RESP);
    kxrj3_reg_value(KXTJ3_WHO_AM_I);
    kxrj3_reg_value(KXTJ3_INT_SOURCE1);
    kxrj3_reg_value(KXTJ3_INT_SOURCE2);
    kxrj3_reg_value(KXTJ3_STATUS_REG);
    kxrj3_reg_value(KXTJ3_INT_REL);
    GR_LOG("    *** R/W ***\r\n");
    
    kxrj3_reg_value(KXTJ3_CTRL_REG1);
    kxrj3_reg_value(KXTJ3_CTRL_REG2);
    kxrj3_reg_value(KXTJ3_INT_CTRL_REG1);
    kxrj3_reg_value(KXTJ3_INT_CTRL_REG2);
    kxrj3_reg_value(KXTJ3_DATA_CTRL_REG);
    kxrj3_reg_value(KXTJ3_WAKEUP_COUNTER);
    kxrj3_reg_value(KXTJ3_NA_COUNTER);
    kxrj3_reg_value(KXTJ3_SELF_TEST);
    kxrj3_reg_value(KXTJ3_WAKEUP_THRESHOLD_H);
    kxrj3_reg_value(KXTJ3_WAKEUP_THRESHOLD_L);
    GR_LOG("-------------------------------------------\r\n");
}

void kxrj3_init(void)
{
    uint16_t trigger_val = 1500<<4;
    uint8_t regValue = 0;
    uint8_t writeValue = 0;
    uint8_t readValue = 0;
    uint8_t regAddr = 0;
    
    kxtj3_int_gpio_init();

#if (0)
    kxrj3_set_ctrl_reg2(1, 0, 0 , 0, 0);
    delay_ms(1000);
    
//    kxrj3_query_reg_value();
    
    kxrj3_set_pc1_mode(0);
    
    kxrj3_set_ctrl_reg1(0, 0, 0, 0, 1);
    
    kxrj3_set_ctrl_reg2(0, 1, 1 , 1, 1);
    
    kxrj3_set_int_ctrl_reg1(1, 1, 0, 0);
    
    kxrj3_set_int_ctrl_reg2(0, 1, 1, 1, 1, 1, 1);
    
    kxrj3_set_data_ctrl_reg(1, 0, 0, 0);
    
    kxrj3_set_wakeup_counter(20);
    
//    kxrj3_set_na_counter(0x02);
    
    kxrj3_set_wakeup_threshold(1500);
    
//    kxrj3_query_reg_value();

#else
    kxrj3_set_ctrl_reg2(1, 0, 1 , 1, 0);
    delay_ms(1000);
        
    kxrj3_set_pc1_mode(0);
    
    kxrj3_set_ctrl_reg1(0, 0, 0, 0, 1);
    
    kxrj3_set_ctrl_reg2(0, 0, 1 , 1, 1);
    
    kxrj3_set_int_ctrl_reg1(1, 1, 0, 0);
    
    kxrj3_set_int_ctrl_reg2(1, 1, 1, 1, 1, 1, 1);
    
    kxrj3_set_data_ctrl_reg(0, 0, 0, 0);
    
    kxrj3_set_wakeup_counter(5);
    
    kxrj3_set_na_counter(0x02);
    
    kxrj3_set_wakeup_threshold(1500);
        
    kxrj3_set_pc1_mode(1);
    
#endif

    
    kxrj3_set_pc1_mode(1);
    
    kxrj3_query_reg_value();
    
//    user_i2c_deinit();
}


//void kxrj3_init(void)
//{
//    kxtj3_int_gpio_init();

//    kxtj3_i2c_write_reg(KXTJ3_CTRL_REG1, 0x00);
//    kxtj3_i2c_write_reg(KXTJ3_CTRL_REG2, 0x80);
//    delay_ms(10);
//    kxtj3_i2c_write_reg(KXTJ3_CTRL_REG2, 0x00);
//    kxtj3_i2c_write_reg(KXTJ3_WAKEUP_COUNTER, 30);
//    kxtj3_i2c_write_reg(KXTJ3_DATA_CTRL_REG, 0x08);
//    kxtj3_i2c_write_reg(KXTJ3_WAKEUP_THRESHOLD_H, 0x5D);
//    kxtj3_i2c_write_reg(KXTJ3_WAKEUP_THRESHOLD_L, 0xC0);
//    kxtj3_i2c_write_reg(KXTJ3_INT_CTRL_REG1, 0x30);
//    kxtj3_i2c_write_reg(KXTJ3_CTRL_REG2, 0x3F);
//    kxtj3_i2c_write_reg(KXTJ3_CTRL_REG1, 0x82);
//    
//    kxrj3_query_reg_value();
//    
//    user_i2c_deinit();
//}


void kxrj3_loop(void)
{
    uint8_t regValue = 0;
    uint8_t writeValue = 0;
    uint8_t readValue = 0;
    uint8_t regAddr = 0;
    
    kxtj3_int_gpio_init();
    
//    regAddr = KXTJ3_INT_CTRL_REG1;
//    writeValue = 0x2F;
//    kxtj3_i2c_write_reg(regAddr, writeValue);
//    kxtj3_i2c_read_reg(regAddr, (uint8_t *)&readValue, 1);
//    kxrj3_check(regAddr, writeValue, readValue);
//    
//    kxrj3_config_reg(KXTJ3_INT_CTRL_REG1, 0x78);
    
    kxrj3_set_ctrl_reg2(1, 0, 1 , 1, 0);
    delay_ms(1000);
    
    kxrj3_query_reg_value();
    
    kxrj3_set_pc1_mode(0);
    
    kxrj3_set_ctrl_reg1(0, 0, 0, 4, 1);
    
    kxrj3_set_ctrl_reg2(0, 0, 1 , 1, 1);
    
    kxrj3_set_int_ctrl_reg1(1, 1, 0, 0);
    
    kxrj3_set_int_ctrl_reg2(1, 1, 1, 1, 1, 1, 1);
    
    kxrj3_set_data_ctrl_reg(0, 1, 0, 1);
    
    kxrj3_set_wakeup_counter(5);
    
    kxrj3_set_na_counter(0x02);
    
    kxrj3_set_wakeup_threshold(1500);
    
    kxrj3_query_reg_value();
    
    kxrj3_set_pc1_mode(1);
    
    kxrj3_query_reg_value();
    
    kxtj3_i2c_read_reg(KXTJ3_INT_REL, (uint8_t *)&regValue, 1);
    
//    kxrj3_query_reg_value();
    
    uint8_t rxAxizBuff[8];
    for(;;)
    {
        
        if(0 != kxtj3_i2c_read_reg(KXTJ3_STATUS_REG, (uint8_t *)&regValue, 1))
        {
            GR_LOG(" Irq read err...\r\n");
            continue;
        }
        if(0x10 == (regValue&0x10))
//        if(0 != kxtjIntFlag)
        {
            kxtjIntFlag = 0;
            if(0 == kxtj3_i2c_read_reg(KXTJ3_INT_SOURCE1, (uint8_t *)&regValue, 1))
            {
                memset((void *)rxAxizBuff, 0, sizeof(rxAxizBuff));
                kxrj3_get_data(rxAxizBuff);
                kxtj3_i2c_read_reg(KXTJ3_INT_REL, (uint8_t *)&regValue, 1);
                GR_LOG(" X_data=0x%02X%02X,", rxAxizBuff[1], rxAxizBuff[0]);
                GR_LOG(" X_data=0x%02X%02X,", rxAxizBuff[3], rxAxizBuff[2]);
                GR_LOG(" X_data=0x%02X%02X", rxAxizBuff[5], rxAxizBuff[4]);
                GR_LOG("\r\n");
            }
            else
            {
                GR_LOG(" INT1 read err\r\n");
            }
        }

    }

}




void kxtj3_irq_callback(void)
{
    uint8_t regValue = 0;
    kxtj3_i2c_read_reg(KXTJ3_INT_REL, (uint8_t *)&regValue, 1);
}





